home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / AEGetIcon sample.sit / AEGetIcon sample / AEGetIcon.c next >
Text File  |  1996-06-23  |  10KB  |  317 lines

  1. /*
  2.  *--------------------------------------------------------------
  3.  * AEGetIcon.c
  4.  *--------------------------------------------------------------
  5.  *    Most of source codes in this file come from FinderDrag
  6.  *    written by Nitin Ganatra -- MacDTS, Apple Computer.
  7.  *    However, the author fully rewrite the source codes to make
  8.  *    it easier to incorporate my programs.
  9.  *--------------------------------------------------------------
  10.  *    This code requires Scriptable Finder (System 7.5 or greater)
  11.  *--------------------------------------------------------------
  12.  */
  13.  
  14. #include <AppleEvents.h>
  15. #include <AERegistry.h>
  16. #include <AEPackObject.h>
  17. #include <Finder.h>
  18. #include <Icons.h>
  19.  
  20. /* Finder specific constant definitions */
  21. #define    kFinderSignature    'MACS'        /* signature */
  22. #define pIconBitmap            'iimg'        /* icon bitmap property */
  23. #define formAlias            typeAlias    /* key desctopr of alias */
  24.  
  25. /*
  26.  *--------------------------------------------------------------
  27.  * function prototype to be included in some appropriate header
  28.  *--------------------------------------------------------------
  29.  */
  30. extern    OSErr GetIconSuiteFromFinder(FSSpecPtr hfsObj, Handle *suite);
  31.  
  32. /*
  33.  *--------------------------------------------------------------
  34.  *    static function prototypes
  35.  *--------------------------------------------------------------
  36.  */
  37. static OSErr AskForPropertyToFinder(FSSpecPtr hfs, const DescType prop, AppleEvent *reply);
  38. static OSErr MakeSpecifierForFile(FSSpecPtr hfs, AEDesc *file);
  39. static OSErr MakePropertySpecifierForSpecifier(DescType prop, AEDesc *spec, AEDesc *propSpec);
  40. static OSErr GetAliasDesc(const FSSpecPtr hfs, AEDesc *aliasDesc);
  41. static Size  GetSizeFromIconType(DescType iconType);
  42. static OSErr BuildIconSuiteFromAEDesc(Handle *suite, AEDesc *family);
  43.  
  44. /*
  45.  *--------------------------------------------------------------
  46.  *    GetIconSuiteFromFinder
  47.  *--------------------------------------------------------------
  48.  *    Get an icon suite from the desktop data base using AppleEvent.
  49.  *    Given handle should be invalid.
  50.  *--------------------------------------------------------------
  51.  */
  52. OSErr GetIconSuiteFromFinder(FSSpecPtr theHFSObj, Handle *iconSuite)
  53. {
  54.     AppleEvent    replyEvent = { typeNull, nil };
  55.     AEDesc        iconFamily = { typeNull, nil };
  56.     OSErr        result;
  57.  
  58.     /* Set up our locals for easy cleanup */
  59.     *iconSuite = nil;
  60.  
  61.     result = AskForPropertyToFinder(theHFSObj, pIconBitmap, &replyEvent);
  62.  
  63.     if (result == noErr) {        
  64.         /* If not, get the icon family and build an icon suite */
  65.         result = AEGetParamDesc(&replyEvent, keyDirectObject, typeWildCard, &iconFamily);
  66.         if (result == noErr) {
  67.             result = BuildIconSuiteFromAEDesc(iconSuite, &iconFamily);
  68.         }
  69.     }
  70.     /* clean up descriptors */
  71.     (void)AEDisposeDesc(&iconFamily);
  72.     (void)AEDisposeDesc(&replyEvent);
  73.  
  74.     return (result);
  75. }
  76. /*
  77.  *--------------------------------------------------------------
  78.  *    AskForPropertyToFinder
  79.  *--------------------------------------------------------------
  80.  *    request a files object's property to finder
  81.  *--------------------------------------------------------------
  82.  */
  83. static OSErr AskForPropertyToFinder(
  84.     FSSpecPtr        theSpec,
  85.     const DescType    theProperty,
  86.     AppleEvent *    theAEReply)
  87. {
  88.     AppleEvent    finderEvent = { typeNull, nil };
  89.     AEDesc        finderTarget = { typeNull, nil };
  90.     AEDesc        fileSpecifier = { typeNull, nil };
  91.     AEDesc        propertySpecifier = { typeNull, nil };
  92.     DescType    finderSign;
  93.     OSErr        result;
  94.  
  95.     finderSign = kFinderSignature;
  96.     result = AECreateDesc(typeApplSignature, &finderSign,
  97.             sizeof(DescType), &finderTarget);
  98.  
  99.     /* make an AppleEvent */
  100.     if (result == noErr) {
  101.         result = AECreateAppleEvent(kAECoreSuite, kAEGetData, &finderTarget, 
  102.             kAutoGenerateReturnID, kAnyTransactionID, &finderEvent);
  103.  
  104.         (void)AEDisposeDesc(&finderTarget);
  105.     }
  106.  
  107.     /* make an object specifier for the interesting file */
  108.     if (result == noErr) {
  109.         result = MakeSpecifierForFile(theSpec, &fileSpecifier);
  110.     }
  111.  
  112.     /* make an icon family property specifier for the file */
  113.     if (result == noErr) {
  114.         result = MakePropertySpecifierForSpecifier(
  115.                     theProperty, &fileSpecifier, &propertySpecifier);
  116.  
  117.         (void)AEDisposeDesc(&fileSpecifier);
  118.     }
  119.  
  120.     /* stuff the icon family property specifier into the AppleEvent */
  121.     if (result == noErr) {
  122.         result = AEPutParamDesc(&finderEvent, keyDirectObject, &propertySpecifier);
  123.  
  124.         (void)AEDisposeDesc(&propertySpecifier);
  125.     }
  126.  
  127.     /* now send the requiest AppleEvent to the Finder */
  128.     if (result == noErr) {
  129.         result = AESend(&finderEvent, theAEReply,
  130.                     kAEWaitReply + kAECanInteract + kAECanSwitchLayer, 
  131.                     kAENormalPriority, kAEDefaultTimeout, nil, nil);
  132.  
  133.         (void)AEDisposeDesc(&finderEvent);
  134.     }
  135.     /* Finder may have sent us an resultor number */
  136.     if (result == noErr) {
  137.         DescType    returnType;
  138.         Size        returnSize;
  139.         long        returnLong;
  140.  
  141.         result = AEGetParamPtr(theAEReply, keyErrorNumber, typeLongInteger, 
  142.                         &returnType, &returnLong, sizeof(long), &returnSize);
  143.         if (result == noErr) {
  144.             result = (OSErr)returnLong;
  145.         } else {
  146.             result = noErr;
  147.         }
  148.     }
  149.     return (result);
  150. }
  151. /*
  152.  *--------------------------------------------------------------
  153.  *    MakeSpecifierForFile
  154.  *--------------------------------------------------------------
  155.  *    make the object specifier
  156.  *--------------------------------------------------------------
  157.  */
  158. static OSErr MakeSpecifierForFile(FSSpecPtr theHFSObj, AEDesc *fileSpecifier)
  159. {
  160.     AEDesc        hfsDesc = { typeNull, nil };
  161.     OSErr        result;
  162.  
  163.     /* create the file descriptor with the FSSpec passed in. */
  164.     result = GetAliasDesc(theHFSObj, &hfsDesc);
  165.  
  166.     /* make the object specifier with a null container
  167.         (i.e., "file of <null>", or just "file") */
  168.     if (result == noErr) {
  169.         AEDesc    nullDesc = { typeNull, nil };
  170.         result = CreateObjSpecifier(typeWildCard, &nullDesc, 
  171.                 formAlias, &hfsDesc, false, fileSpecifier);
  172.  
  173.         (void)AEDisposeDesc(&hfsDesc);
  174.     }
  175.     return(result);
  176. }
  177. /*
  178.  *--------------------------------------------------------------
  179.  *    MakePropertySpecifierForSpecifier
  180.  *--------------------------------------------------------------
  181.  *     create a property specifier for the object specifier
  182.  *--------------------------------------------------------------
  183.  */
  184. static OSErr MakePropertySpecifierForSpecifier(DescType theProperty, 
  185.             AEDesc *ofSpecifier, AEDesc *propertySpecifier)
  186. {
  187.     AEDesc        keyData = { typeNull, nil };
  188.     OSErr        result;
  189.  
  190.     /* Create a 'type' AEDesc with the desired property */
  191.     result = AECreateDesc(typeType, &theProperty, sizeof(DescType), &keyData);
  192.  
  193.     /* With it create a property specifier for the object specifier passed to us */
  194.     if (result == noErr) {
  195.         result = CreateObjSpecifier(cProperty, ofSpecifier, 
  196.                 formPropertyID, &keyData, false, propertySpecifier);
  197.  
  198.         (void)AEDisposeDesc(&keyData);    
  199.     }
  200.     return result;
  201. }
  202. /*
  203.  *--------------------------------------------------------------
  204.  * GetAliasDesc
  205.  *--------------------------------------------------------------
  206.  *    returns alias descriptor of the HFS object
  207.  *--------------------------------------------------------------
  208.  */
  209. static OSErr GetAliasDesc(const FSSpecPtr theSpec, AEDesc *theAliasDesc)
  210. {
  211.     AliasHandle    anAlias = nil;
  212.     OSErr        result;
  213.  
  214.     /* create an alias record of the target HFS object */
  215.     result = NewAlias(nil, theSpec, &anAlias);
  216.  
  217.     /* create a list element of the target HFS object */
  218.     if (result == noErr) {
  219.         HLock((Handle)anAlias);
  220.         result = AECreateDesc(typeAlias, *anAlias, GetHandleSize((Handle)anAlias), theAliasDesc);
  221.         DisposeHandle((Handle)anAlias);
  222.     }
  223.     return(result);
  224. }
  225. /*
  226.  *--------------------------------------------------------------
  227.  *    BuildIconSuiteFromAEDesc
  228.  *--------------------------------------------------------------
  229.  *    this uses the Apple Event Manager to pick the icon data
  230.  *    out of the 'ifam' AEDesc
  231.  *--------------------------------------------------------------
  232.  */
  233. static OSErr BuildIconSuiteFromAEDesc(Handle *iconSuite, AEDesc *iconFam)
  234. {
  235.     AERecord    anAERec = { typeNull, nil };
  236.     Ptr            iconBff = nil;
  237.     DescType    typeArray[6] = {
  238.                     large1BitMask, large4BitData, large8BitData,
  239.                     small1BitMask, small4BitData, small8BitData
  240.                 };
  241.     Boolean        maskAdded = false;
  242.     OSErr        result;
  243.  
  244.     /* allocate working buffer */
  245.     iconBff = NewPtr(kLarge8BitIconSize);
  246.     result = MemError();
  247.  
  248.     /* create a  new icon suite */
  249.     if (result == noErr) {    
  250.         result = NewIconSuite(iconSuite);
  251.     }
  252.  
  253.     /* coerce the icon desctiptor to desctiptor record so that
  254.          we can pick up the icon data using AEKeyword */
  255.     if (result == noErr) {    
  256.         result = AECoerceDesc(iconFam, typeAERecord, (AEDesc *)&anAERec);
  257.     }
  258.  
  259.     /* now pick up each icon family */
  260.     if (result == noErr) {    
  261.         int    familyCount;
  262.  
  263.         for (familyCount = 0; familyCount < 6; familyCount ++) {
  264.             /* loop through the suite and grab the data from the AERecord for
  265.             each type of icon we're interested in. */
  266.             DescType    iconType, typeCode;
  267.             Size        iconSize;
  268.  
  269.             iconType = typeArray[familyCount];
  270.             result = AEGetKeyPtr(&anAERec, iconType, iconType, &typeCode, 
  271.                             iconBff, kLarge8BitIconSize, &iconSize);
  272.         
  273.             if (result == noErr) {
  274.                 /* We don't set the error code for this unless the NewHandle
  275.                 call fails, because it's possible that the 'ifam' doesn't
  276.                 have an icon for one that we're interested in. */
  277.                 Handle anIcon = NewHandle(iconSize);
  278.         
  279.                 if (anIcon != nil) {
  280.                     /* OK, the memory alloc succeeded and we have data. Copy
  281.                     it into the allocated icon and add it to the suite. 
  282.                     Set atLeastOne to true, to indicate later that we did
  283.                     in fact add at least one icon to this suite. */
  284.                     BlockMoveData(iconBff, *anIcon, iconSize);
  285.                     result = AddIconToSuite(anIcon, *iconSuite, iconType);
  286.                     if (result == noErr) {
  287.                         if (iconType == large1BitMask) {
  288.                             maskAdded = true;
  289.                         }
  290.                     }
  291.                 } else {
  292.                     result = MemError();
  293.                 }
  294.             }
  295.         }
  296.         (void)AEDisposeDesc(&anAERec);
  297.     }
  298.     if (maskAdded && (result == errAEDescNotFound)) {
  299.         /* this means some of family members were
  300.          not found but the suite is still valid */
  301.         result = noErr;
  302.     }
  303.     else if (result != noErr) {
  304.         /* There was either an error in a memory allocation, or something
  305.         else went wrong (like no mask was added to the suite).
  306.         Get rid of the partially created suite. */
  307.         if (*iconSuite != nil) {
  308.             DisposeIconSuite(*iconSuite, true);
  309.             *iconSuite = nil;
  310.         }
  311.     }
  312.     if (iconBff != nil) {
  313.         DisposePtr(iconBff);
  314.     }
  315.     return (result);
  316. }
  317.